package de.hbrs.ooka.beans;

import de.hbrs.ooka.entities.ConferenceEntity;
import de.hbrs.ooka.entities.UserEntity;
import de.hbrs.ooka.enums.Role;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TransactionRequiredException;

@Stateless
public class UserBeanStateless implements UserBeanStatelessLocal {

    @PersistenceContext(unitName = "CRS_PU")
    private EntityManager em;

    @EJB
    private ConferenceBeanStatelessLocal confBean;
    
    @Override
    public UserEntity getUser(int id) {
        return em.find(UserEntity.class, id);
    }

    @Override
    public UserEntity getUser(String name) {
        Query q = em.createNamedQuery("findUserByName", UserEntity.class).setParameter("name", name);
        List<UserEntity> resultList = q.getResultList();

        if (resultList.size() != 1) {
            throw new IllegalArgumentException("Wrong Query: " + resultList.size());
        }
        return resultList.get(0);
    }

    @Override
    public UserEntity registerUser(String name, String password) {
        UserEntity user = null;
        try {
            user = new UserEntity();
            user.addRole(Role.PARTICIPANT);
            if (name.equals("admin")) {
                user.addRole(Role.REVIEWER);
                user.addRole(Role.ORGANIZER);
            }
            user.setName(name.toLowerCase());
            user.setPassword(password);
            em.persist(user);
        } catch (EntityExistsException e) {
            System.out.println("ERROR in RegisterNewUserStateless: EntityExistsException: " + e.getMessage());
        } catch (IllegalArgumentException e) {
            System.out.println("ERROR in RegisterNewUserStateless: IllegalArgumentException" + e.getMessage());
        } catch (TransactionRequiredException e) {
            System.out.println("ERROR in RegisterNewUserStateless: TransactionRequiredException" + e.getMessage());
        } catch (Exception e) {
            System.out.println("ERROR in RegisterNewUserStateless: Exception" + e.getMessage());
        }
        return user;
    }

    @Override
    public UserEntity checkLogin(String name, String password) {
        Query qu = em.createNamedQuery("findUserByName").setParameter("name", name.toLowerCase());
        List<UserEntity> users = qu.getResultList();

        for (UserEntity u : users) {
            if (u.getPassword().equals(password)) {
                return u;
            }
        }
        return null;
    }

    @Override
    public List<UserEntity> getAllUsers() {
        Query q = em.createNamedQuery("findAllUsers");
        List<UserEntity> resultList = q.getResultList();
        for (UserEntity userEntity : resultList) {
            em.detach(userEntity);
        }

        return resultList;
    }

    @Override
    public boolean registerAtConf(UserEntity user, ConferenceEntity conf) {
        user.addConference(conf);
        conf.addParticipant(user);
        em.merge(user);
        em.merge(conf);
        //em.find(ConferenceEntity.class, conf.getId()).addParticipant(user);
        return true;
    }

    @Override
    public void assignRights(String userName, String[] roles) {
        UserEntity user = this.getUser(Integer.parseInt(userName));
        user.setRoles(roles);
    }

    @Override
    public double getReputation(UserEntity user) {
                
        List<ConferenceEntity> confs = new ArrayList<ConferenceEntity>();
        
        for (ConferenceEntity conferenceEntity : confBean.getAllConferences()) {
            if(conferenceEntity.getOrganizer().equals(user) && conferenceEntity.getReputationList().size() > 0){
                //nicht bewertete Konferenzen nicht berücksichtigen
                confs.add(conferenceEntity);
            }
        }
        
        if ( confs.isEmpty() ) {
            return 0.0;
        }
        
        double reputation = 0.0;
        for (ConferenceEntity c : confs) {
            reputation += c.getReputation();
        }
        return reputation / confs.size();
    }
}
